package com.dubbo.gmail.controller;

import com.dubbo.gmail.api.service.AsyncHelloService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

@Controller
public class AsyncHelloController {

    @DubboReference
    AsyncHelloService asyncHelloService;

    @RequestMapping("/asyncHello")
    @ResponseBody
    public String asyncHello() throws InterruptedException, ExecutionException, TimeoutException {
        CompletableFuture<String> pppd = asyncHelloService.sayHelloAsync("pppd");
        String s = pppd.get(6000, TimeUnit.SECONDS);
        return s;
    }

    @RequestMapping("/sayHelloContextAsync")
    @ResponseBody
    public String sayHelloContextAsync() throws InterruptedException, ExecutionException, TimeoutException {
        CompletableFuture<String> pppd = asyncHelloService.sayHelloContextAsync("pdd too");
        String s = pppd.get(6000, TimeUnit.SECONDS);
        return s;
    }

    @RequestMapping("/sayHelloWhenComplete1")
    @ResponseBody
    public String sayHelloWhenComplete1() {
        CompletableFuture<String> future = asyncHelloService.sayHelloWhenComplete("pdd complete too");
        System.out.println(new Date());
        AtomicReference<String> s = new AtomicReference<>("");
        future.whenComplete((v, t) -> {
            if (t != null) {
                t.printStackTrace();
            } else {
                System.out.println(new Date());
                s.set("Response: " + v);
            }
        });
        return s.get();
    }

    @RequestMapping("/sayHelloWhenComplete2")
    @ResponseBody
    public String sayHelloWhenComplete2() throws ExecutionException, InterruptedException {
        asyncHelloService.sayHelloWhenComplete("pdd complete too");
//        CompletableFuture<String> future = RpcContext.getContext().asyncCall(
//                () -> {
//                    asyncHelloService.sayHelloWhenComplete("oneway call request1");
//                }
//        );
        CompletableFuture<String> future = RpcContext.getContext().asyncCall(() -> asyncHelloService.sayHelloWhenComplete("oneway call request1").get());
        return future.get();
    }
}
